package com.example.utils.mybatis;

import com.google.common.base.CaseFormat;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 扩展 Mybatis 注解，作用于 where 条件操作上
 */
public class SimpleSelectLanguageDriver extends XMLLanguageDriver implements LanguageDriver {

    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {

        // 正则匹配
        Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            StringBuilder builder = new StringBuilder();
            builder.append("<where> ");

            for (Field field : parameterType.getDeclaredFields()) {
                // 排除被 Invisble 修饰的变量
                if (!field.isAnnotationPresent(Invisible.class)) {

                    // 用于 if 条件中的基本类型（默认值）判断
                    List<String> keys = Arrays.asList("long", "int");
                    String fieldType = field.getGenericType().getTypeName().toLowerCase(); // 字段类型
                    fieldType = fieldType.contains(".") ? fieldType.substring(fieldType.lastIndexOf(".")) : fieldType;

                    boolean flag = false;
                    for (String key : keys) {
                        if (fieldType.contains(key)) {
                            flag = true;
                            break;
                        }
                    }

                    String str = flag ? "<if test=\"_field != null &amp;&amp; _field != 0\">AND _column=#{_field}</if>" : "<if test=\"_field != null \">AND _column=#{_field}</if>";
                    builder.append(str.replaceAll("_field", field.getName()).replaceAll("_column", CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));
                }
            }

            builder.append(" </where>");

            script = matcher.replaceAll(builder.toString());
            script = "<script>" + script + "</script>";

            System.out.println("SimpleSelectLanguageDriver - 生成的SQL：" + script);
        }

        return super.createSqlSource(configuration, script, parameterType);
    }
}
